package parser;

import java.util.ArrayList;
import java.util.List;
import net.sf.jsqlparser.expression.AllComparisonExpression;
import net.sf.jsqlparser.expression.AnyComparisonExpression;
import net.sf.jsqlparser.expression.CaseExpression;
import net.sf.jsqlparser.expression.DateValue;
import net.sf.jsqlparser.expression.DoubleValue;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.expression.InverseExpression;
import net.sf.jsqlparser.expression.JdbcParameter;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.TimeValue;
import net.sf.jsqlparser.expression.TimestampValue;
import net.sf.jsqlparser.expression.WhenClause;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.Between;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.SubSelect;

public class ExpressionParser implements ExpressionVisitor
{
	private entity.Table entityTable;
	private List<Integer> rowList;
	private Object value;
	public List<Integer> getRow(Expression expression,entity.Table entityTable)
	{
		this.entityTable = entityTable;
		rowList = new ArrayList<Integer>();
		expression.accept(this);
		return rowList;
		
	}
	
	public Object getValue(Expression expression)
	{
		expression.accept(this);
		return value;
	}
	
	@Override
	public void visit(NullValue arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(Function arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(InverseExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(JdbcParameter arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(DoubleValue doubleValue) 
	{
		
	}
	@Override
	public void visit(LongValue longValue) 
	{
		value = longValue.getStringValue();
	}
	@Override
	public void visit(DateValue arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(TimeValue arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(TimestampValue arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(Parenthesis arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(StringValue stringValue) 
	{
		value=stringValue.getValue();
	}
	@Override
	public void visit(Addition arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(Division arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(Multiplication arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(Subtraction arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(AndExpression andExpression) 
	{
		ExpressionParser parser = new ExpressionParser();
		List<Integer> row1,row2;
		row1 = parser.getRow(andExpression.getLeftExpression(),entityTable);
		row2 = parser.getRow(andExpression.getRightExpression(),entityTable);
		for (int i=0;i<row1.size();i++)
			for (int j=0;j<row2.size();j++) if (row1.get(i).equals(row2.get(j))) rowList.add(row1.get(i));
	}
	@Override
	public void visit(OrExpression orExpression) 
	{
		ExpressionParser parser = new ExpressionParser();
		List<Integer> row1,row2;
		row1 = parser.getRow(orExpression.getLeftExpression(),entityTable);
		row2 = parser.getRow(orExpression.getRightExpression(),entityTable);
		for (int i=0;i<row1.size();i++) rowList.add(row1.get(i));
		
		for (int i=0;i<row2.size();i++)
		{
			boolean t=true;
			for (int j=0;j<rowList.size();j++) if (rowList.get(j).equals(row2.get(i))) t=false;
			if (t) rowList.add(row2.get(i));
			
		}
			
	}
	@Override
	public void visit(Between arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(EqualsTo equalsTo) 
	{	
		ExpressionParser parser = new ExpressionParser();
		Object value1 = parser.getValue(equalsTo.getLeftExpression());
		Object value2 = parser.getValue(equalsTo.getRightExpression());
		
		if ((value1 instanceof Column)&&(value2 instanceof Column))
		{
			String columnName1 = ((Column)value1).getWholeColumnName();
			String columnName2 = ((Column)value2).getWholeColumnName();
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName1)==null) continue;
				if (entityTable.getColumnByName(columnName2)==null) continue;
				if (entityTable.getColumnByName(columnName1).getDataAt(i).equals(entityTable.getColumnByName(columnName2).getDataAt(i)))
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof Column)&&(value2 instanceof String))
		{
			String columnName = ((Column)value1).getWholeColumnName();

			String value = (String)value2;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				if (entityTable.getColumnByName(columnName).getDataAt(i).equals(value))
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof String)&&(value2 instanceof Column))
		{
			String columnName = ((Column)value2).getWholeColumnName();

			String value = (String)value1;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				if (entityTable.getColumnByName(columnName).getDataAt(i).equals(value))
				{
					rowList.add(i);
				}
			}
		}
	}
	@Override
	public void visit(GreaterThan greaterThan) 
	{
		ExpressionParser parser = new ExpressionParser();
		Object value1 = parser.getValue(greaterThan.getLeftExpression());
		Object value2 = parser.getValue(greaterThan.getRightExpression());
		
		if ((value1 instanceof Column)&&(value2 instanceof Column))
		{
			String columnName1 = ((Column)value1).getWholeColumnName();
			String columnName2 = ((Column)value2).getWholeColumnName();
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName1)==null) continue;
				if (entityTable.getColumnByName(columnName2)==null) continue;
				String data1 = entityTable.getColumnByName(columnName1).getDataAt(i);
				String data2 = entityTable.getColumnByName(columnName2).getDataAt(i);
				if (SelectParser.compareValue(data1, data2)>0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof Column)&&(value2 instanceof String))
		{
			String columnName = ((Column)value1).getWholeColumnName();

			String value = (String)value2;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)>0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof String)&&(value2 instanceof Column))
		{
			String columnName = ((Column)value2).getWholeColumnName();

			String value = (String)value1;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)<0)
				{
					rowList.add(i);
				}
			}
		}
	}
	@Override
	public void visit(GreaterThanEquals greaterThanEquals) 
	{
		ExpressionParser parser = new ExpressionParser();
		Object value1 = parser.getValue(greaterThanEquals.getLeftExpression());
		Object value2 = parser.getValue(greaterThanEquals.getRightExpression());
		
		if ((value1 instanceof Column)&&(value2 instanceof Column))
		{
			String columnName1 = ((Column)value1).getWholeColumnName();
			String columnName2 = ((Column)value2).getWholeColumnName();
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName1)==null) continue;
				if (entityTable.getColumnByName(columnName2)==null) continue;
				String data1 = entityTable.getColumnByName(columnName1).getDataAt(i);
				String data2 = entityTable.getColumnByName(columnName2).getDataAt(i);
				if (SelectParser.compareValue(data1, data2)>=0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof Column)&&(value2 instanceof String))
		{
			String columnName = ((Column)value1).getWholeColumnName();

			String value = (String)value2;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)>=0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof String)&&(value2 instanceof Column))
		{
			String columnName = ((Column)value2).getWholeColumnName();

			String value = (String)value1;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)<=0)
				{
					rowList.add(i);
				}
			}
		}
	}
	@Override
	public void visit(InExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(IsNullExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(LikeExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(MinorThan minorThan) 
	{
		ExpressionParser parser = new ExpressionParser();
		Object value1 = parser.getValue(minorThan.getLeftExpression());
		Object value2 = parser.getValue(minorThan.getRightExpression());
		
		if ((value1 instanceof Column)&&(value2 instanceof Column))
		{
			String columnName1 = ((Column)value1).getWholeColumnName();
			String columnName2 = ((Column)value2).getWholeColumnName();
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName1)==null) continue;
				if (entityTable.getColumnByName(columnName2)==null) continue;
				String data1 = entityTable.getColumnByName(columnName1).getDataAt(i);
				String data2 = entityTable.getColumnByName(columnName2).getDataAt(i);
				if (SelectParser.compareValue(data1, data2)<0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof Column)&&(value2 instanceof String))
		{
			String columnName = ((Column)value1).getWholeColumnName();

			String value = (String)value2;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)<0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof String)&&(value2 instanceof Column))
		{
			String columnName = ((Column)value2).getWholeColumnName();

			String value = (String)value1;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)>0)
				{
					rowList.add(i);
				}
			}
		}
	}
	@Override
	public void visit(MinorThanEquals minorThanEquals) 
	{
		ExpressionParser parser = new ExpressionParser();
		Object value1 = parser.getValue(minorThanEquals.getLeftExpression());
		Object value2 = parser.getValue(minorThanEquals.getRightExpression());
		
		if ((value1 instanceof Column)&&(value2 instanceof Column))
		{
			String columnName1 = ((Column)value1).getWholeColumnName();
			String columnName2 = ((Column)value2).getWholeColumnName();
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName1)==null) continue;
				if (entityTable.getColumnByName(columnName2)==null) continue;
				String data1 = entityTable.getColumnByName(columnName1).getDataAt(i);
				String data2 = entityTable.getColumnByName(columnName2).getDataAt(i);
				if (SelectParser.compareValue(data1, data2)<=0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof Column)&&(value2 instanceof String))
		{
			String columnName = ((Column)value1).getWholeColumnName();

			String value = (String)value2;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)<=0)
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof String)&&(value2 instanceof Column))
		{
			String columnName = ((Column)value2).getWholeColumnName();

			String value = (String)value1;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				String data = entityTable.getColumnByName(columnName).getDataAt(i);
				if (SelectParser.compareValue(data, value)>=0)
				{
					rowList.add(i);
				}
			}
		}
	}
	@Override
	public void visit(NotEqualsTo notEqualsTo) 
	{
		ExpressionParser parser = new ExpressionParser();
		Object value1 = parser.getValue(notEqualsTo.getLeftExpression());
		Object value2 = parser.getValue(notEqualsTo.getRightExpression());
		
		if ((value1 instanceof Column)&&(value2 instanceof Column))
		{
			String columnName1 = ((Column)value1).getWholeColumnName();
			String columnName2 = ((Column)value2).getWholeColumnName();
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName1)==null) continue;
				if (entityTable.getColumnByName(columnName2)==null) continue;
				if (!entityTable.getColumnByName(columnName1).getDataAt(i).equals(entityTable.getColumnByName(columnName2).getDataAt(i)))
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof Column)&&(value2 instanceof String))
		{
			String columnName = ((Column)value1).getWholeColumnName();

			String value = (String)value2;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				if (!entityTable.getColumnByName(columnName).getDataAt(i).equals(value))
				{
					rowList.add(i);
				}
			}
		}
		else if ((value1 instanceof String)&&(value2 instanceof Column))
		{
			String columnName = ((Column)value2).getWholeColumnName();

			String value = (String)value1;
			if (value==null || value.equals("")) return; 
			for (int i=0;i<entityTable.getRowCount();i++)
			{
				if (entityTable.getColumnByName(columnName)==null) continue;
				if (!entityTable.getColumnByName(columnName).getDataAt(i).equals(value))
				{
					rowList.add(i);
				}
			}
		}
	}
	@Override
	public void visit(Column column) 
	{
		value= column;
	}
	@Override
	public void visit(SubSelect arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(CaseExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(WhenClause arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(ExistsExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(AllComparisonExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(AnyComparisonExpression arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void visit(Concat arg0) {
		// TODO Auto-generated method stub
		
	}
	
}
